code source game Bi-a 3D

23.690 lượt xem;
1 using System.Collections;
2 using
System.Collections.Generic;
3 using
System.Linq;
4 using
UnityEngine;
5 using
ThreeDPool.EventHandlers;
6 using
ThreeDPool.Controllers;
7 using
ThreeDPool.UIControllers;
8
9 namespace
ThreeDPool.Managers
10 {

11     ///
<summary>
12     ///
This class is a rule manager for this pool game
13     ///
decides on the players playing
14     ///
calculates score and decides the fate of the ball and the players after each turn
15     ///

16     ///
</summary>
17     
public class GameManager : Singleton<GameManager>
18     {
19         
public enum GameType
20         {
21             JustCue =
1,
22             ThreeBall =
3,
23             SixBall =
6,
24             SevenBall,
25         }
26
27         
public enum GameState
28         {
29             Practise =
1,
30             GetSet,
31             Play,
32             Pause,
33             Complete
34         }
35
36         
// update the players you would be playing this round
37         
[SerializeField]
38         
private string[] _playerNames;
39
40         
[SerializeField]
41         
private GameType _gameType;
42
43         
[SerializeField]
44         
private Transform _rackTransform;
45
46         
[SerializeField]
47         
private CueBallController _cueBall;
48
49         
[SerializeField]
50         
private GameUIScreen _gameUIScreen;
51
52         
// maintaining a queue here so that we dont have to worry about maintain a separate field for the player turn
53         
private Queue<Player> _players = new Queue<Player>();
54
55         
private List<CueBallController> _ballsPocketed;
56         
private List<CueBallController> _ballsHitOut;
57         
private GameState _currGameState;
58         
private GameState _prevGameState;
59         
private bool _ballsInstantiated;
60
61         
public int NumOfBallsStriked;
62
63         
public GameState CurrGameState { get { return _currGameState; } }
64         
public GameState PrevGameState { get { return _prevGameState; } }
65
66         
public Queue<Player> Players { get { return _players; } }
67
68         
public string[] Winners;
69
70         
public int NumOfTimesPlayed { private set; get; }
71
72         
protected override void Start()
73         {
74             
base.Start();
75
76             ChangeGameState(GameState.Practise);
77             NumOfBallsStriked =
0;
78
79             
if (_playerNames != null)
80             {
81                 
foreach (var playerName in _playerNames)
82                 {
83                     
var player = new Player(playerName);
84
85                     _players.Enqueue(player);
86                 }
87             }
88
89             
// declare the ballspotted and ballshit out array
90             
// consider all the balls are either potted or hitout,
91             
// lets fix the array size based on game type + cueball
92             
int arraySize = (int)_gameType + 1;
93             _ballsPocketed =
new List<CueBallController>(arraySize);
94             _ballsHitOut =
new List<CueBallController>(arraySize);
95
96             
// create player uis
97             _gameUIScreen.CreatePlayerUI();
98
99             
// the first player in the queue will be playing first
100
101         }

102
103         ///
<summary>
104         ///
This function places the ball based on the game type
105         ///
There are prefabs created in a order to make the placement easy based on the selected game type
106         ///
</summary>
107         
private void PlaceBallBasedOnGameType()
108         {
109             
// just cue doesnt place any balls in the table except for the cueball
110             
if (_gameType != GameType.JustCue)
111             {
112                 
string rackString = "Rack";
113                 Instantiate((Resources.Load(_gameType.ToString() + rackString,
typeof(GameObject)) as GameObject), _rackTransform.position, _rackTransform.rotation);
114             }
115         }
116
117         
private bool IsGameComplete()
118         {
119             
if (_ballsPocketed.Count() == (int)_gameType)
120                 
return true;
121
122             
return false;
123         }
124
125         
private IEnumerator OnGameComplete()
126         {
127             
yield return new WaitForEndOfFrame();
128
129             
int winningScore = 0;
130
131             
// get the highest score
132             
foreach (var player in _players)
133             {
134                 
if (player.Score >= winningScore)
135                     winningScore = player.Score;
136             }
137
138             
// now that we have found the winning score, check if there is anyone else with the same score
139             Winners = _players.Where(p => p.Score == winningScore).Select(p => p.Name).ToArray();
140
141             
// give enough time for the ball, cue and camera to return back to its original position
142             EventManager.Notify(
typeof(GameStateEvent).Name, this, new GameStateEvent() { GameState = GameStateEvent.State.Complete });
143         }
144
145         
private void SetNewPlayerTurn()
146         {
147             
// next player takes the chance
148             Player player = _players.Dequeue();
149             _players.Enqueue(player);
150
151             
// get the player on peek to diplay the turn
152             Player newPlayer = _players.Peek();
153             EventManager.Notify(
typeof(GameStateEvent).Name, this, new GameStateEvent() { CurrPlayer = newPlayer.Name });
154         }
155
156         
private void CalculateThePointAndNextTurn()
157         {
158             
// now that all the ball are stationary, lets decide on next state of game
159             
// check the balls pocketed list, first for the cueball and then to the count
160             
// if there is a cue ball in the list then the current player looses a point, and the cue ball is placed in the table
161             
// else then the score is count for the current player
162             
// then check if there are any ball in the floor
163             
// if there is any they get placed in their respective position
164             Player currPlayer = _players.Peek();
165
166             
// check if the player has striked the ball
167             
if (currPlayer.HasStrikedBall)
168             {
169                 CueBallController whiteBall = _ballsPocketed.FirstOrDefault(b => b.BallType == CueBallController.CueBallType.White);
170                 
if (whiteBall != null)
171                 {
172                     
// player looses score
173                     currPlayer.CalculateScore(-
1);
174
175                     
// remove the white ball from pocket
176                     _ballsPocketed.Remove(whiteBall);
177
178                     
// set all pocketed balls to true, as the ball pocketed along with the white ball is considered already pocketed
179                     _ballsPocketed.ForEach(b => b.IsPocketedInPrevTurn =
true);
180
181                     
// place the cue ball back in the table
182                     whiteBall.PlaceBallInInitialPos();
183
184                     SetNewPlayerTurn();
185                 }
186                 
else
187                 {
188                     
if (_ballsPocketed.Count() > 0)
189                     {
190                         
// get the balls that are currently pockted, the currently pocketed ball will have a value set to false
191                         
var ballsCurrentlyPocketed = _ballsPocketed.Where(b => b.IsPocketedInPrevTurn == false);
192                         Debug.Log(
"Balls Currently Pocketed" + ballsCurrentlyPocketed.Count());
193                         
if (ballsCurrentlyPocketed.Count() > 0)
194                         {
195                             
// count for the number of balls pocketed, and increment the player score
196                             currPlayer.CalculateScore(ballsCurrentlyPocketed.Count());
197
198                             
// set all pocketed balls to true
199                             _ballsPocketed.ForEach(b => b.IsPocketedInPrevTurn =
true);
200
201                             
// player continues to play
202                         }
203                         
else
204                         {
205                             SetNewPlayerTurn();
206                         }
207                     }
208                     
else
209                     {
210                         SetNewPlayerTurn();
211                     }
212                 }
213
214                 
// place these balls back in the pool table
215                 
foreach (var ballHitOut in _ballsHitOut)
216                     ballHitOut.PlaceBallInInitialPos();
217             }
218
219             
// clear up every information
220             _ballsHitOut.Clear();
221
222             
// reset players state
223             
foreach (var player in _players)
224             {
225                 
// checking if the current player in iteration is the first player and setting the state accordingly
226                 
// only the first player in the queue is in playing state
227                 
// note: state is set based on the condition
228                 player.SetPlayingState((player == _players.Peek()));
229             }
230
231             
// check if all balls in the game are pocketed
232             
if (IsGameComplete())
233                 StartCoroutine(OnGameComplete());
234             
else
235                 EventManager.Notify(
typeof(CueBallActionEvent).Name, this, new CueBallActionEvent() { State = CueBallActionEvent.States.Stationary });
236         }
237
238         
public void ChangeGameState(GameState newGameState)
239         {
240             
// making sure that the prev game state is actually the prev game state
241             
if(newGameState != _currGameState)
242             {
243                 _prevGameState = _currGameState;
244                 _currGameState = newGameState;
245             }
246         }
247
248         
public void OnGetSet()
249         {
250             ChangeGameState(GameState.GetSet);
251         }
252
253         
public void OnPlay()
254         {
255             
// make sure we start with clear list
256             _ballsHitOut.Clear();
257             _ballsPocketed.Clear();
258
259             NumOfBallsStriked =
0;
260
261             NumOfTimesPlayed++;
262
263             
foreach (var player in _players)
264                 player.ResetScore();
265
266             ChangeGameState(GameState.Play);
267
268             
// place the cue ball in position
269             _cueBall.PlaceBallInInitialPos();
270
271             
if (!_ballsInstantiated)
272             {
273                 
// place the ball in the rack position
274                 PlaceBallBasedOnGameType();
275
276                 _ballsInstantiated =
true;
277             }
278         }
279
280         
public void OnPaused()
281         {
282             ChangeGameState(GameState.Pause);
283         }
284
285         
public void OnContinue()
286         {
287             ChangeGameState(GameState.Play);
288         }
289
290         
// this function will be called by cueball when they come to rest after the shot is taken
291         
public void ReadyForNextRound()
292         {
293             
// lets allow the player to take some shot while the game is not started yet
294             
if (CurrGameState == GameState.Practise)
295             {
296                 
// white ball might be pocketed or hit out
297                 
// since there is only white before the Play state dont have to check for the ball type, just see which array has the ball object
298                 _cueBall.PlaceBallInPosWhilePractise();
299             }
300             
// pause is added to just make sure its ready for next round
301             
else if(CurrGameState == GameState.Play || CurrGameState == GameState.Pause)
302             {
303                 NumOfBallsStriked--;
304
305                 
// all the balls in the pool table are now stationary, let the game continue
306                 
if (NumOfBallsStriked == 0)
307                     CalculateThePointAndNextTurn();
308             }
309             
else
310             {
311                 
// do nothing
312             }
313         }
314
315         
public void AddToBallPocketedList(CueBallController ball)
316         {
317             
// making sure we are not adding a ball multiple times
318             
if (!_ballsPocketed.Contains(ball))
319                 _ballsPocketed.Add(ball);
320         }
321
322         
public void AddToBallHitOutList(CueBallController ball)
323         {
324             
// these balls will be back on pool table
325             
// check if the ball is already potted too and then fell on floor
326             
if (!_ballsHitOut.Contains(ball) && !_ballsPocketed.Contains(ball))
327                 _ballsHitOut.Add(ball);
328         }
329     }
330 }


Gõ tìm kiếm nhanh...